public class solutionFromIdeaCase {
	//recursion control methods - This class will cause the Solution Count to trigger, which updates the case. We need to close 
	//the loop to avoid recursive solution creation.
	private static boolean alreadyCreatedSolution = false;
    public static boolean hasAlreadyCreatedSolution() 
    {
    return alreadyCreatedSolution;
    }
    public static void setAlreadyCreatedSolution() 
    {
    alreadyCreatedSolution = true;
    }
    //end recursion control methods
    
    //This method is designed to create a specially formatted solution every time a case is saved with a status of 'Idea Submitted'.
    //We decided to use this method in order to bypass the case closure process.
	public static void createSolution(case[] cases, case[] oldCases)
	{
		if (!solutionFromIdeaCase.hasAlreadyCreatedSolution()) 
        { 
			map<id,case> caseMap = new map<id,case>();
			list<id> caseIdList = new list<id>();
			list<id> softwareProductIdList = new list<id>();
			for (integer i = 0; i < cases.size(); i++)
			{
				If (cases[i].status == 'User Story Review' & oldCases[i].status != 'User Story Review')
				{
					casemap.put(cases[i].id,cases[i]);
					caseIdList.add(cases[i].id);
					softwareProductIdList.add(cases[i].software_product__c);
				}
			}
			if (caseIdList.size()>0)
			{
				
				Map<string,string> solutionRecordTypeNameIdMap = New Map<string,string>();
				Map<id,string> softwareProductRecordTypeIdNameMap = New Map<id,string>();
				For(recordType rt :[select id,name,sobjecttype from recordtype where sobjecttype in ('solution','software_product__c')])
				{
					If (rt.sobjecttype=='software_product__c')
					{
						softwareProductRecordTypeIdNameMap.put(rt.id,rt.name);
					}
					else if(rt.sobjecttype=='solution')
					{
						solutionRecordTypeNameIdMap.put(rt.name,rt.id);	
					}
				}
				Map<id,id> SoftwareProductIdRecordTypeIdMap = New Map<id,id>();
				For (software_Product__c sp : [select id,recordtypeid from software_product__c where id in :softwareProductIdList])
				{
					SoftwareProductIdRecordTypeIdMap.put(sp.id,sp.recordtypeid);
				}
				List<solution> insertSolutions = New List<solution>();
				List<CaseSolution> insertCaseSolutions = New List<CaseSolution>();
				for (integer x = 0; x < caseIdList.size(); x++)
				{
					Solution s = new Solution();
					Case ideaCase = caseMap.get(caseIdList[x]);
					system.debug(ideacase.software_product__c);
					if(solutionRecordTypeNameIdMap.get(softwareProductRecordTypeIdNameMap.get(SoftwareProductIdRecordTypeIdMap.get(ideacase.software_product__c)))!= Null)
					{
						s.recordTypeId = solutionRecordTypeNameIdMap.get(softwareProductRecordTypeIdNameMap.get(SoftwareProductIdRecordTypeIdMap.get(ideacase.software_product__c)));
					}
					s.solutionName = ideacase.subject;
					s.solutionNote = ('PROBLEM: <br />' + ideacase.description + '<br /> <br />SOLUTION:  <br /> <br /> <br /> This issue has been sent to the community as an idea.');
					s.send_to_ideas__c = true;
					insertSolutions.add(s);
				}
				insert insertSolutions;
				for (integer x = 0; x < caseIdList.size(); x++)
				{
					CaseSolution cs = new CaseSolution();
					Case ideaCase = caseMap.get(caseIdList[x]);
					cs.SolutionId = insertSolutions[x].Id;
					cs.CaseId = ideaCase.Id;
					insertCaseSolutions.add(cs);
				}
				insert insertCaseSolutions;
				setAlreadyCreatedSolution();	
			}
        }
	}
}